package com.mydubbo.invoker;

import java.lang.reflect.Method;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import com.alibaba.fastjson.JSON;
import com.mydubbo.core.MyDubboReferStarter;
import com.mydubbo.loadbalance.LoadBalance;
import com.mydubbo.rpc.Rpc;
import com.mydubbo.rpc.Sender;
import com.mydubbo.rpc.Server;
import com.mydubbo.rpc.dto.Request;
import com.mydubbo.rpc.dto.Response;

public class Invoker {
	
	private LoadBalance loadBalance;
	private Server server;
	private static ConcurrentHashMap<String, Sender> senderMap = new ConcurrentHashMap<>();
	
	public Invoker(LoadBalance loadBalance, Server server) {
		this.loadBalance = loadBalance;
		this.server = server;
	}
	
	public Object invoke(Class<?> clazz, Method method, Object[] args) {
		
		List<String> addressList = MyDubboReferStarter.getInstance().getServiceServer(clazz.getName());
		String address = loadBalance.select(addressList);
		Sender sender = senderMap.get(address);
		if(sender==null) {
			senderMap.putIfAbsent(address, server.connect(address));
		}
		sender = senderMap.get(address);
		Request request = new Request();
		String id = UUID.randomUUID().toString();
		request.setId(id);
		request.setClazz(clazz);
		request.setMethod(method.getName());
		request.setParameterTypes(method.getParameterTypes());
		request.setReturnType(method.getReturnType());
		request.setArgs(args);
		String message = JSON.toJSONString(request);
		Rpc rpc = new Rpc();
		Rpc.putRpc(id, rpc);
		sender.sendMessage(message);
		
		Response response = rpc.getResponse();
		
		return response.getData();
	}

}
